package com.sf.dlb.service;

import com.sf.dlb.bean.VideoRquestBean;
import com.sf.dlb.config.Global;
import com.sf.dlb.constant.CacheConstant;
import com.sf.dlb.constant.ResponseConstant;
import com.sf.dlb.jpa.model.VideoRecordInfo;
import com.sf.dlb.jpa.repository.VideoRecordRepository;
import com.sf.dlb.mongo.model.VideoList;
import com.sf.dlb.mongo.repository.VideoListRepository;
import com.sf.dlb.utils.DateUtils;
import com.sf.dlb.utils.GsonUtils;
import com.sf.dlb.utils.ResultVOUtil;
import com.sf.dlb.utils.StringFormatUtils;
import com.sf.dlb.vo.PageVO;
import com.sf.dlb.vo.ResultVO;
import com.sf.dlb.vo.VideoGetDlbVO;
import com.sf.dlb.vo.VideoListVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by jing.tan on 2018/5/21.
 */
@Service
public class VideoListService extends BaseService{
    private static Logger logger = LoggerFactory.getLogger(VideoListService.class);

    @Autowired
    private VideoListRepository videoListRepository;
    @Autowired
    private VideoRecordRepository videoRecordRepository;
    @Autowired
    private UserWalletService userWalletService;
    @Autowired
    private Global global;
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 查询视频列表
     * @param videoRquestBean
     * @return
     */
    public ResultVO findbyList(VideoRquestBean videoRquestBean){
        logger.info("findbyList start ");
        int currentPages=videoRquestBean.getCurrentPages();
        int pageSize=videoRquestBean.getPageSize();
        String videoId=videoRquestBean.getVideoId();
        String userId=videoRquestBean.getUserId();
        //分页查询
        Sort sort = new Sort(Sort.Direction.DESC, "createDate");
        VideoList videoList=new VideoList();
        videoList.setDelFlag("0");
        Example example=Example.of(videoList);
        Pageable pageable = new PageRequest(currentPages,pageSize,sort);
        Page<VideoList> videoPages= videoListRepository.findAll(example,pageable);
        List<VideoList> videoLists=videoPages.getContent();
        if(CollectionUtils.isEmpty(videoLists)) {
            return ResultVOUtil.error(ResponseConstant.ERROR,"视频列表为空");
        }
        //客户端最新看到的视频时间，计算用户这次更新了多少条视频
        Date createDate=null;
        int refreshCount=-1;
        if(StringUtils.isNoneBlank(videoId)){
            VideoList videoList1=videoListRepository.findByIdAndDelFlag(videoId,"0");
            createDate=(null!=videoList1?videoList1.getCreateDate():null);
            refreshCount=0;
        }
        //封装Vo
        ArrayList<VideoListVO> dataListBeans=new ArrayList<>();
        PageVO pageVO=new PageVO();
        //查询播放记录
        List<VideoRecordInfo> videoRecordInfos= videoRecordRepository.findByUserIdAndDelFlag(userId,"0");
        for (VideoList videoList1:videoLists) {
            VideoListVO videoListVO=new VideoListVO();
            BeanUtils.copyProperties(videoList1,videoListVO);
            String title=new String(Base64Utils.decodeFromString(videoList1.getTitle()));
            videoListVO.setTitle(title);
            String source=new String(Base64Utils.decodeFromString(videoList1.getSource()));
            videoListVO.setSource(source);
            videoListVO.setGetDlbState(isGetDlb(videoRecordInfos,videoList1.getId()+""));
            videoListVO.setPlayState(isPlay(videoRecordInfos,videoList1.getId()+""));
            videoListVO.setTime(DateUtils.timeFormatWhatBefore(videoList1.getCreateDate()));
            videoListVO.setVideoId(videoList1.getId()+"");
            dataListBeans.add(videoListVO);
            //计算用户这次更新了多少条视频
            if(null!=createDate&&videoList1.getCreateDate().getTime()>createDate.getTime()){
                refreshCount++;
            }
        }
        //如果没有传videoId 默认刷新数=查询数
        if(refreshCount<0){
            refreshCount=dataListBeans.size();
        }
        pageVO.setDataList(dataListBeans);
        pageVO.setPageSize(pageSize);
        pageVO.setCurrentPages(currentPages+1);//默认从0开始，返回前端要+1;
        pageVO.setFirstPage(videoPages.isFirst());
        pageVO.setLastPage(videoPages.isLast());
        pageVO.setTotalElements(videoPages.getTotalElements());
        pageVO.setTotalPages(videoPages.getTotalPages());
        pageVO.setRefreshNumber(refreshCount);
        return ResultVOUtil.success(pageVO);
    }
    /**
     * 查询视频列表(未注册)
     * @param videoRquestBean
     * @return
     */
    public ResultVO findbyListNotLogin(VideoRquestBean videoRquestBean){
        logger.info("findbyList start ");
        int currentPages=videoRquestBean.getCurrentPages();
        int pageSize=videoRquestBean.getPageSize();
        String videoId=videoRquestBean.getVideoId();
        //分页查询
        Sort sort = new Sort(Sort.Direction.DESC, "createDate");
        VideoList videoList=new VideoList();
        videoList.setDelFlag("0");
        Example example=Example.of(videoList);
        Pageable pageable = new PageRequest(currentPages,pageSize,sort);
        Page<VideoList> videoPages= videoListRepository.findAll(example,pageable);
        List<VideoList> videoLists=videoPages.getContent();
        if(CollectionUtils.isEmpty(videoLists)) {
            return ResultVOUtil.error(ResponseConstant.ERROR,"视频列表为空");
        }
        //客户端最新看到的视频时间，计算用户这次更新了多少条视频
        Date createDate=null;
        int refreshCount=-1;
        if(StringUtils.isNoneBlank(videoId)){
            VideoList videoList1=videoListRepository.findByIdAndDelFlag(videoId,"0");
            createDate=(null!=videoList1?videoList1.getCreateDate():null);
            refreshCount=0;
        }
        //封装Vo
        ArrayList<VideoListVO> dataListBeans=new ArrayList<>();
        PageVO pageVO=new PageVO();
        for (VideoList videoList1:videoLists) {
            VideoListVO videoListVO=new VideoListVO();
            BeanUtils.copyProperties(videoList1,videoListVO);
            String title=new String(Base64Utils.decodeFromString(videoList1.getTitle()));
            videoListVO.setTitle(title);
            String source=new String(Base64Utils.decodeFromString(videoList1.getSource()));
            videoListVO.setSource(source);
            videoListVO.setTime(DateUtils.timeFormatWhatBefore(videoList1.getCreateDate()));
            videoListVO.setVideoId(videoList1.getId()+"");
            dataListBeans.add(videoListVO);
            //计算用户这次更新了多少条视频
            if(null!=createDate&&videoList1.getCreateDate().getTime()>createDate.getTime()){
                refreshCount++;
            }
        }
        //如果没有传videoId 默认刷新数=查询数
        if(refreshCount<0){
            refreshCount=dataListBeans.size();
        }
        pageVO.setDataList(dataListBeans);
        pageVO.setPageSize(pageSize);
        pageVO.setCurrentPages(currentPages+1);//默认从0开始，返回前端要+1;
        pageVO.setFirstPage(videoPages.isFirst());
        pageVO.setLastPage(videoPages.isLast());
        pageVO.setTotalElements(videoPages.getTotalElements());
        pageVO.setTotalPages(videoPages.getTotalPages());
        pageVO.setRefreshNumber(refreshCount);
        return ResultVOUtil.success(pageVO);
    }
    /**
     * 开始播放
     */
    @Transactional
    public ResultVO startPlay(VideoRquestBean videoRquestBean){
        logger.info("startPlay start videoRquestBean={} ", GsonUtils.getInstance().toJson(videoRquestBean));
        //是否已读
        String videoId=videoRquestBean.getVideoId();
        String userId=videoRquestBean.getUserId();
        VideoList videoList=videoListRepository.findByIdAndDelFlag(videoId,"0");
        if(videoList==null){
            logger.info("startPlay 此视频不存在 ");
            return ResultVOUtil.success();
        }
        VideoRecordInfo videoRecordInfo= videoRecordRepository.findByUserIdAndVideoIdAndDelFlag(userId,videoId,"0");
        if(null!=videoRecordInfo){
            logger.info("startPlay 此视频已播放 ");
            return ResultVOUtil.success();
        }
        //保存阅读记录
        videoRecordInfo=new VideoRecordInfo();
        videoRecordInfo.setUserId(userId);
        videoRecordInfo.setVideoId(videoId);
        videoRecordInfo.setGetState("0");
        videoRecordInfo.setStartTime(new Date());
        videoRecordInfo.setCreateDate(new Date());
        videoRecordInfo.setUpdateDate(new Date());
        videoRecordRepository.save(videoRecordInfo);
        return ResultVOUtil.success();
    }
    /**
     * 结束播放
     */
    @Transactional
    public ResultVO endPlay(VideoRquestBean videoRquestBean){
        logger.info("endPlay start videoRquestBean={} ",GsonUtils.getInstance().toJson(videoRquestBean));
        String videoId=videoRquestBean.getVideoId();
        String userId=videoRquestBean.getUserId();
        //判断是否并发访问-redis
        boolean playFlag=isConcurrent(CacheConstant.USER_VIDEO_PALY_CONCURRENT_PREFIX+userId+":"+videoId);
        if(playFlag){
            logger.info("endPlay 并发访问 ");
            return ResultVOUtil.error(ResponseConstant.ERROR,"");
        }
        VideoRecordInfo videoRecordInfo= videoRecordRepository.findByUserIdAndVideoIdAndDelFlag(userId,videoId,"0");
        if(null==videoRecordInfo){
            logger.info("endPlay 此视频未开始播放 ");
            return ResultVOUtil.error(ResponseConstant.ERROR,"");
        }
        //如果结束时间已存在，就不再计算
        Date endTimeD=videoRecordInfo.getEndTime();
        if(null!=endTimeD){
            logger.info("endPlay 此视频已结束播放 ");
            return ResultVOUtil.error(ResponseConstant.ERROR,"");
        }
        //计算播放时间
        Date startTime=videoRecordInfo.getStartTime();
        Date endTime=new Date();
        long compare=DateUtils.differTimeLong(startTime,endTime)/1000; //秒
        //记录结束时间，状态
        videoRecordInfo.setEndTime(endTime);
        videoRecordInfo.setPlayTimeLong((int)compare);
        videoRecordInfo.setGetState("0");
        videoRecordInfo.setUpdateDate(new Date());
        videoRecordRepository.save(videoRecordInfo);
        //判断有效播放
        VideoList videoList = videoListRepository.findByIdAndDelFlag(videoId,"0");
        Integer getDlbTime=videoList.getGetDlbTime();
        boolean timeFlag=compare>=getDlbTime;//播放时间有效标识(结束时间-开始时间>=有效阅读时间)
        String createDate=DateUtils.formatDate(new Date(),"yyyy-MM-dd");
        List<VideoRecordInfo> videoRecordInfos = videoRecordRepository.findByUserIdAndCreateDateAndDelFlag(userId,createDate,"0");//播放数量
        boolean numberFlag=((CollectionUtils.isEmpty(videoRecordInfos)||videoRecordInfos.size()<global.video_play_getdlb_number)?true:false);
        logger.info("endPlay  getDlbTime={},timeFlag={},numberFlag",getDlbTime,timeFlag,numberFlag);
        if(timeFlag&&numberFlag){
            logger.info("endPlay userId={},videoId={}",userId,videoId);
            ResultVO resultVO=videoGetDlb(userId,videoId);
            return resultVO;
        }
        return ResultVOUtil.success();
    }
    /**
     * 奖励dlb
     */
    @Transactional
    private ResultVO videoGetDlb(String userId,String videoId){
        logger.info("videoGetDlb start userId={},videoId={}",userId,videoId);
        VideoRecordInfo videoRecordInfo= videoRecordRepository.findByUserIdAndVideoIdAndDelFlag(userId,videoId,"0");
        if(null==videoRecordInfo){
            logger.info("videoGetDlb 此视频未开始播放 ");
            return ResultVOUtil.error(ResponseConstant.ERROR,"");
        }
        //计算此视频领取的dlb
        double currentGetDlb=global.video_play_getdlb_yield;
        //更新播放记录为已领取
        videoRecordInfo.setGetState("1");
        videoRecordInfo.setGetNumber(currentGetDlb);
        videoRecordInfo.setUpdateDate(new Date());
        videoRecordRepository.save(videoRecordInfo);
        //更新用户钱包
        userWalletService.updateUserWallet(userId,currentGetDlb,ResponseConstant.source_type_video,ResponseConstant.source_type_video_value+":videoId:"+videoId);
        //响应VO
        VideoGetDlbVO videoGetDlbVO=new VideoGetDlbVO();
        videoGetDlbVO.setGetDlb(StringFormatUtils.kill3Decimals(currentGetDlb));
        videoGetDlbVO.setVideoId(videoId);
        return ResultVOUtil.success(videoGetDlbVO);
    }
    /**
     * 是否已播放
     * @param videoId
     * @return 0未读，1已读
     * @return
     */
    public String isPlay(List<VideoRecordInfo> videoRecordInfos, String videoId){
        boolean isPlayFlag=false;
        for (VideoRecordInfo videoRecordInfo:videoRecordInfos) {
            if(StringUtils.equals(videoRecordInfo.getVideoId(),videoId)){
                isPlayFlag=true;
            }
        }
        if(!isPlayFlag){
            return "0";
        }else{
            return "1";
        }
    }
    /**
     * 是否已领取dlb
     * @param videoId
     * @return 0未领取，1已领取
     * @return
     */
    public String isGetDlb(List<VideoRecordInfo> videoRecordInfos, String videoId){
        boolean isGetDlbFlag=false;
        for (VideoRecordInfo videoRecordInfo:videoRecordInfos) {
            if(StringUtils.equals(videoRecordInfo.getVideoId(),videoId)&&StringUtils.equals(videoRecordInfo.getGetState(),"1")){
                isGetDlbFlag=true;
            }
        }
        if(!isGetDlbFlag){
            return "0";
        }else{
            return "1";
        }
    }
}
